package org.ccay.security.reaml.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;

import org.ccay.core.request.IApplicationPrincipal;
import org.ccay.security.dao.ISecurityInfoDao;
import org.ccay.security.entity.Permission;
import org.ccay.security.entity.Program;
import org.ccay.security.entity.Role;
import org.ccay.security.entity.User;
import org.ccay.security.reaml.ISecurityInfoProvider;
import org.ccay.security.vo.ProgramRolesDTO;


public class SecurityInfoProvider implements ISecurityInfoProvider{
	
	private ISecurityInfoDao securityInfoDao;

	public void setSecurityInfoDao(ISecurityInfoDao securityInfoDao) {
		this.securityInfoDao = securityInfoDao;
	}

	@Override
	public User findAuthenticationInfo(User principal) {
		return securityInfoDao.findAuthenticationInfo(principal);
	}


	@SuppressWarnings("unchecked")
	@Override
	public Set<Permission> findPermissions(Collection<Long> roleIds, User user,IApplicationPrincipal application) {
		if(roleIds.isEmpty()){
			return Collections.EMPTY_SET;
		}
		return securityInfoDao.findPermissions(new ArrayList<Long>(roleIds),application);
	}

	@Override
	public Map<Program, LinkedHashSet<Role>> findProgramRoles(User principal,IApplicationPrincipal application) {
		List<ProgramRolesDTO> items = securityInfoDao.findProgramRoles(principal,application);
		Map<Program, LinkedHashSet<Role>> result = new HashMap<Program, LinkedHashSet<Role>>();
		for(ProgramRolesDTO dto : items){
			Program program = new Program(dto.getProgramId(),dto.getProgramName());
			if(!result.containsKey(program)){
				result.put(program, new LinkedHashSet<Role>());
			}
			//program
			program = getProgramfromSet(program,result.keySet());
			
			if(!program.getDimensions().containsKey(dto.getDimension())){
				program.getDimensions().put(dto.getDimension(), new LinkedHashSet<Serializable>());
			}
			//dimension values 
			LinkedHashSet<Serializable> dimensionValues = program.getDimensions().get(dto.getDimension());
			dimensionValues.add(dto.getValue());
			
			//roles
			LinkedHashSet<Role> roles = result.get(program);
			roles.add(new Role(dto.getRoleId(),dto.getRoleName()));
		}
		return result;
	}
	
	
	private Program getProgramfromSet(Program program , Set<Program> programSet) {
		for(Program item : programSet){
			if(program.equals(item)){
				return item;
			}
		}
		return null;
	}

}
